gh-153400: Fall back to __NR_getrandom when SYS_getrandom is unavailable - #155762
gh-153400: Fall back to __NR_getrandom when SYS_getrandom is unavailable#155762jjhelmus wants to merge 4 commits into
Conversation
Replace libc's SYS_getrandom with the kernel-provided __NR_getrandom in configure checks, os.getrandom(), and interpreter entropy handling.
|
Hi, I think this is not a trivial change, so the related issue is required. |
vstinner
left a comment
There was a problem hiding this comment.
In the commit message, you can document that __NR_getrandom comes from Linux kernel <unistd.h>, whereas SYS_getrandom comes from glibc <sys/syscall.h>.
| # endif | ||
| # if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL) | ||
| # include <sys/syscall.h> // SYS_getrandom | ||
| # include <sys/syscall.h> // __NR_getrandom |
There was a problem hiding this comment.
This include should be removed, __NR_getrandom comes from <unistd.h> which is already included above.
__NR_getrandom comes the kernel header files, like /usr/include/asm/unistd_64.h on my Fedora 44. <sys/syscall.h> is the glibc header file which provides SYS_getrandom constant, but this change replace __NR_getrandom with SYS_getrandom.
There was a problem hiding this comment.
I think the chain for __NR_getrandom is <sys/syscall.h> -> <asm/unistd.h>
For SYS_getrandom, <sys/syscall.h> -> <bits/syscall.h>
I could not find a path from <unistd.h> to either of these symbols.
| [ | ||
| AC_LANG_SOURCE([[ | ||
| #include <stddef.h> | ||
| #include <unistd.h> |
There was a problem hiding this comment.
| #include <unistd.h> // __NR_getrandom |
| AC_LANG_SOURCE([[ | ||
| #include <stddef.h> | ||
| #include <unistd.h> | ||
| #include <sys/syscall.h> |
There was a problem hiding this comment.
Since SYS_getrandom is no longer used, <sys/syscall.h> include can be removed, no?
There was a problem hiding this comment.
With the change to falling back to __NR_getrandom only when SYS_getrandom is undefined this is include is still needed.
There was a problem hiding this comment.
| #include <linux/random.h> // GRND_NONBLOCK |
|
I don't know how Solaris, FreeBSD and OpenBSD expose their syscall numberes: |
This is exactly the case that python-build-standalone is running into on x86-64. The target is glibc 2.17 which does not included getrandom and the Debian package providing it is built against a a kernel that does not include SYS_getrandom. The build uses a modern UAPI kernel heads so __NR_getrandom is available. |
Do you mean that glibc 2.17 doesn't provide |
Which Linux kernel version are you used to build Python? |
Often not, glibc 2.17 was released in 2012. The the getrandom syscall was added to the kernel in 2014 with 3.17. The specifics for python-build-standalone are glibc 2.19 build against kernel 3.16. So no Note that the glib 2.17 packages in RHEL 9 and derivates likely include the macro because the syscall list was updated to include calls from the 5.4 kernel. |
I don't know "UAPI kernel headers". How do they work? |
|
If we want to maximize compatibility I think we should rather check for both |
By UAPI headers, I mean the Linux kernel’s userspace API headers, the headers needed to compile userspace programs including CPython. These are distinct from the headers used to compile external kernel modules. On Debian, the userspace headers are provided by python-build-standalone installs these header from Linux 7.0.12 and places them before the sysroot headers in the search path. Consequently, newer kernel syscall numbers such as |
Use the libc-provided SYS_getrandom syscall number when available, falling back to the kernel-provided __NR_getrandom when necessary.
Agreed. I'ved update the PR to use |
Fall back to the kernel-provided
__NR_getrandomin configure checks,os.getrandom(), and interpreter entropy handling when libcSYS_getrandomis not available.This makes
os.getrandom()available when building against an older glibc that was itself built with kernel headers lacking the syscall, provided the current kernel headers define __NR_getrandom. This type of build is done in python-build-standalone, astral-sh/python-build-standalone#1188.